﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySqlProvider.Enums;
using DatabaseExtension.ConnectionString;
using DatabaseExtension;

namespace MySqlProvider.ConnectionString
{
    public class MySqlConnectionInfo : ConnectionInfo
    {
        public MySql.Data.MySqlClient.MySqlConnectionStringBuilder MySqlConnectionStringBuilder
        {
            get
            {
                return base.ConnectionStringBuilder as MySql.Data.MySqlClient.MySqlConnectionStringBuilder;
            }
        }
        #region ConnectionStringBuilder Derived Parameter
        /// <summary>
        /// When true, multiple SQL statements can be sent with one command execution.
        /// </summary>
        public Boolean AllowBatching
        {
            get
            {
                return this.MySqlConnectionStringBuilder.AllowBatch;
            }
            set
            {
                this.MySqlConnectionStringBuilder.AllowBatch = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean AllowUserVariables
        {
            get
            {
                return this.MySqlConnectionStringBuilder.AllowUserVariables;
            }
            set
            {
                this.MySqlConnectionStringBuilder.AllowUserVariables = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean AllowZeroDateTime
        {
            get
            {
                return this.MySqlConnectionStringBuilder.AllowZeroDateTime;
            }
            set
            {
                this.MySqlConnectionStringBuilder.AllowZeroDateTime = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean AutoEnlist
        {
            get
            {
                return this.MySqlConnectionStringBuilder.AutoEnlist;
            }
            set
            {
                this.MySqlConnectionStringBuilder.AutoEnlist = value;
            }
        }
        /// <summary>
        /// Pattern that matches columns that should not be treated as UTF8.
        /// </summary>
        public String BlobAsUTF8ExcludePattern
        {
            get
            {
                return this.MySqlConnectionStringBuilder.BlobAsUTF8ExcludePattern;
            }
            set
            {
                this.MySqlConnectionStringBuilder.BlobAsUTF8ExcludePattern = value;
            }
        }
        /// <summary>
        /// Pattern that matches columns that should be treated as UTF8.
        /// </summary>
        public String BlobAsUTF8IncludePattern
        {
            get
            {
                return this.MySqlConnectionStringBuilder.BlobAsUTF8IncludePattern;
            }
            set
            {
                this.MySqlConnectionStringBuilder.BlobAsUTF8IncludePattern = value;
            }
        }
        /// <summary>
        /// no description...
        /// </summary>
        public Boolean CacheServerProperties
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CacheServerProperties;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CacheServerProperties = value;
            }
        }
        /// <summary>
        /// This option specifies the path to a certificate file in PFX format.
        /// </summary>
        public String CertificateFile
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CertificateFile;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CertificateFile = value;
            }
        }
        /// <summary>
        /// This option allows you to specify a password which is used in conjunction with a certificate specified using the option CertificateFile.
        /// </summary>
        public String CertificatePassword
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CertificatePassword;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CertificatePassword = value;
            }
        }
        /// <summary>
        /// This option allows you to access a certificate held in a personal store, rather than use a certificate file and password combination.
        /// </summary>
        public MySql.Data.MySqlClient.MySqlCertificateStoreLocation CertificateStoreLocation
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CertificateStoreLocation;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CertificateStoreLocation = value;
            }
        }
        /// <summary>
        /// This option allows you to access a certificate held in a personal store, rather than use a certificate file and password combination.
        /// </summary>
        public String CertificateThumbprint
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CertificateThumbprint;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CertificateThumbprint = value;
            }
        }
        /// <summary>
        /// Specifies the character set that should be used to encode all queries sent to the server.
        /// </summary>
        public String CharacterSet
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CharacterSet;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CharacterSet = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean CheckParameters
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CheckParameters;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CheckParameters = value;
            }
        }
        /// <summary>
        /// no description...
        /// </summary>
        public String CommandInterceptors
        {
            get
            {
                return this.MySqlConnectionStringBuilder.CommandInterceptors;
            }
            set
            {
                this.MySqlConnectionStringBuilder.CommandInterceptors = value;
            }
        }
        /// <summary>
        /// This is useful in clustered configurations to force load balancing between a running server and a server just brought online.
        /// </summary>
        public uint ConnectionLifeTime
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ConnectionLifeTime;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ConnectionLifeTime = value;
            }
        }
        /// <summary>
        /// Specifies the type of connection to make to the server.
        /// </summary>
        public MySql.Data.MySqlClient.MySqlConnectionProtocol ConnectionProtocol
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ConnectionProtocol;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ConnectionProtocol = value;
            }
        }
        /// <summary>
        /// When true, indicates the connection state is reset when removed from the pool.
        /// </summary>
        public Boolean ConnectionReset
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ConnectionReset;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ConnectionReset = value;
            }
        }
        /// <summary>
        /// The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.
        /// </summary>
        public uint ConnectionTimeout
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ConnectionTimeout;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ConnectionTimeout = value;
            }
        }
        /// <summary>
        /// True to return DateTime.MinValue for date or datetime columns that have illegal values.
        /// </summary>
        public Boolean ConvertZeroDateTime
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ConvertZeroDateTime;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ConvertZeroDateTime = value;
            }
        }
        /// <summary>
        /// no description...
        /// </summary>
        public uint DefaultCommandTimeout
        {
            get
            {
                return this.MySqlConnectionStringBuilder.DefaultCommandTimeout;
            }
            set
            {
                this.MySqlConnectionStringBuilder.DefaultCommandTimeout = value;
            }
        }
        /// <summary>
        /// no description...
        /// </summary>
        public int DefaultTableCacheAge
        {
            get
            {
                return this.MySqlConnectionStringBuilder.DefaultTableCacheAge;
            }
            set
            {
                this.MySqlConnectionStringBuilder.DefaultTableCacheAge = value;
            }
        }
        /// <summary>
        /// no description...
        /// </summary>
        public String ExceptionInterceptors
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ExceptionInterceptors;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ExceptionInterceptors = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean FunctionsReturnString
        {
            get
            {
                return this.MySqlConnectionStringBuilder.FunctionsReturnString;
            }
            set
            {
                this.MySqlConnectionStringBuilder.FunctionsReturnString = value;
            }
        }
        /// <summary>
        /// If you want to use server-side prepare statements, set this option to false.
        /// </summary>
        public Boolean IgnorePrepare
        {
            get
            {
                return this.MySqlConnectionStringBuilder.IgnorePrepare;
            }
            set
            {
                this.MySqlConnectionStringBuilder.IgnorePrepare = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean IntegratedSecurity
        {
            get
            {
                return this.MySqlConnectionStringBuilder.IntegratedSecurity;
            }
            set
            {
                this.MySqlConnectionStringBuilder.IntegratedSecurity = value;
            }
        }
        /// <summary>
        /// no documentation provided.
        /// </summary>
        public Boolean InteractiveSession
        {
            get
            {
                return this.MySqlConnectionStringBuilder.InteractiveSession;
            }
            set
            {
                this.MySqlConnectionStringBuilder.InteractiveSession = value;
            }
        }
        /// <summary>
        /// For TCP connections, idle connection time measured in seconds, before the first keepalive packet is sent. A value of 0 indicates that keepalive is not used.
        /// </summary>
        public uint Keepalive
        {
            get
            {
                return this.MySqlConnectionStringBuilder.Keepalive;
            }
            set
            {
                this.MySqlConnectionStringBuilder.Keepalive = value;
            }
        }
        /// <summary>
        /// When true, various pieces of information is output to any configured TraceListeners.
        /// </summary>
        public Boolean Logging
        {
            get
            {
                return this.MySqlConnectionStringBuilder.Logging;
            }
            set
            {
                this.MySqlConnectionStringBuilder.Logging = value;
            }
        }
        /// <summary>
        /// The maximum number of connections allowed in the pool.
        /// </summary>
        public uint MaximumPoolSize
        {
            get
            {
                return this.MySqlConnectionStringBuilder.MaximumPoolSize;
            }
            set
            {
                this.MySqlConnectionStringBuilder.MaximumPoolSize = value;
            }
        }
        /// <summary>
        /// The minimum number of connections allowed in the pool.
        /// </summary>
        public uint MinimumPoolSize
        {
            get
            {
                return this.MySqlConnectionStringBuilder.MinimumPoolSize;
            }
            set
            {
                this.MySqlConnectionStringBuilder.MinimumPoolSize = value;
            }
        }
        /// <summary>
        /// True to treat data type BINARY(16) as GUIDs, otherwise CHAR(36).
        /// </summary>
        public Boolean OldGuids
        {
            get
            {
                return this.MySqlConnectionStringBuilder.OldGuids;
            }
            set
            {
                this.MySqlConnectionStringBuilder.OldGuids = value;
            }
        }
        /// <summary>
        /// no description provided.
        /// </summary>
        public Boolean PersistSecurityInfo
        {
            get
            {
                return this.MySqlConnectionStringBuilder.PersistSecurityInfo;
            }
            set
            {
                this.MySqlConnectionStringBuilder.PersistSecurityInfo = value;
            }
        }
        /// <summary>
        /// When set to the name of a named pipe, the MySqlConnection will attempt to connect to MySQL on that named pipe.
        /// </summary>
        public String PipeName
        {
            get
            {
                return this.MySqlConnectionStringBuilder.PipeName;
            }
            set
            {
                this.MySqlConnectionStringBuilder.PipeName = value;
            }
        }
        /// <summary>
        /// When true, the MySqlConnection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool.
        /// </summary>
        public Boolean Pooling
        {
            get
            {
                return this.MySqlConnectionStringBuilder.Pooling;
            }
            set
            {
                this.MySqlConnectionStringBuilder.Pooling = value;
            }
        }
        /// <summary>
        /// no description provided.
        /// </summary>
        public uint Port
        {
            get
            {
                return this.MySqlConnectionStringBuilder.Port;
            }
            set
            {
                this.MySqlConnectionStringBuilder.Port = value;
            }
        }
        /// <summary>
        /// Sets (or get) the size of the stored procedure cache.
        /// </summary>
        public uint ProcedureCacheSize
        {
            get
            {
                return this.MySqlConnectionStringBuilder.ProcedureCacheSize;
            }
            set
            {
                this.MySqlConnectionStringBuilder.ProcedureCacheSize = value;
            }
        }
        /// <summary>
        /// no description provided.
        /// </summary>
        public Boolean Replication
        {
            get
            {
                return this.MySqlConnectionStringBuilder.Replication;
            }
            set
            {
                this.MySqlConnectionStringBuilder.Replication = value;
            }
        }
        /// <summary>
        /// Setting this option to false means that Connector/NET will ignore a column's binary flags as set by the server.
        /// </summary>
        public Boolean RespectBinaryFlags
        {
            get
            {
                return this.MySqlConnectionStringBuilder.RespectBinaryFlags;
            }
            set
            {
                this.MySqlConnectionStringBuilder.RespectBinaryFlags = value;
            }
        }
        /// <summary>
        /// The name of the shared memory object to use for communication if the connection protocol is set to memory.
        /// </summary>
        public String SharedMemoryName
        {
            get
            {
                return this.MySqlConnectionStringBuilder.SharedMemoryName;
            }
            set
            {
                this.MySqlConnectionStringBuilder.SharedMemoryName = value;
            }
        }
        /// <summary>
        /// no description provided.
        /// </summary>
        public Boolean SqlServerMode
        {
            get
            {
                return this.MySqlConnectionStringBuilder.SqlServerMode;
            }
            set
            {
                this.MySqlConnectionStringBuilder.SqlServerMode = value;
            }
        }
        /// <summary>
        /// SSL connection mode.
        /// </summary>
        public MySql.Data.MySqlClient.MySqlSslMode SslMode
        {
            get
            {
                return this.MySqlConnectionStringBuilder.SslMode;
            }
            set
            {
                this.MySqlConnectionStringBuilder.SslMode = value;
            }
        }
        /// <summary>
        /// no description provided.
        /// </summary>
        public Boolean TableCaching
        {
            get
            {
                return this.MySqlConnectionStringBuilder.TableCaching;
            }
            set
            {
                this.MySqlConnectionStringBuilder.TableCaching = value;
            }
        }
        /// <summary>
        /// Should binary blobs be treated as UTF8.
        /// </summary>
        public Boolean TreatBlobsAsUTF8
        {
            get
            {
                return this.MySqlConnectionStringBuilder.TreatBlobsAsUTF8;
            }
            set
            {
                this.MySqlConnectionStringBuilder.TreatBlobsAsUTF8 = value;
            }
        }
        /// <summary>
        /// Setting this value to false indicates that TINYINT(1) will be treated as an INT.
        /// </summary>
        public Boolean TreatTinyAsBoolean
        {
            get
            {
                return this.MySqlConnectionStringBuilder.TreatTinyAsBoolean;
            }
            set
            {
                this.MySqlConnectionStringBuilder.TreatTinyAsBoolean = value;
            }
        }
        /// <summary>
        /// When true the connection will report changed rows instead of found rows.
        /// </summary>
        public Boolean UseAffectedRows
        {
            get
            {
                return this.MySqlConnectionStringBuilder.UseAffectedRows;
            }
            set
            {
                this.MySqlConnectionStringBuilder.UseAffectedRows = value;
            }
        }
        /// <summary>
        /// Setting this option to true enables compression of packets exchanged between the client and the server.
        /// </summary>
        public Boolean UseCompression
        {
            get
            {
                return this.MySqlConnectionStringBuilder.UseCompression;
            }
            set
            {
                this.MySqlConnectionStringBuilder.UseCompression = value;
            }
        }
        /// <summary>
        /// Indicates that performance counters should be updated during execution.
        /// </summary>
        public Boolean UsePerformanceMonitor
        {
            get
            {
                return this.MySqlConnectionStringBuilder.UsePerformanceMonitor;
            }
            set
            {
                this.MySqlConnectionStringBuilder.UsePerformanceMonitor = value;
            }
        }
        /// <summary>
        /// Logs inefficient database operations.
        /// </summary>
        public Boolean UseUsageAdvisor
        {
            get
            {
                return this.MySqlConnectionStringBuilder.UseUsageAdvisor;
            }
            set
            {
                this.MySqlConnectionStringBuilder.UseUsageAdvisor = value;
            }
        }
        #endregion
        /// <summary>
        /// Manage MySQL Boolean through the Enumerator Flags. Set only if needed.
        /// </summary>
        public MySqlFlags BooleanFlags
        {
            get
            {
                return this._BooleanFlags;
            }
            set
            {
                var tmp = this.MySqlConnectionStringBuilder;
                tmp.AllowBatch = value.HasFlag(MySqlFlags.AllowBatching);
                tmp.AllowUserVariables = value.HasFlag(MySqlFlags.AllowUserVariables);
                tmp.AllowZeroDateTime = value.HasFlag(MySqlFlags.AllowZeroDateTime);
                tmp.AutoEnlist = value.HasFlag(MySqlFlags.AutoEnlist);
                tmp.CacheServerProperties = value.HasFlag(MySqlFlags.CacheServerProperties);
                tmp.CheckParameters = value.HasFlag(MySqlFlags.CheckParameters);
                tmp.ConnectionReset = value.HasFlag(MySqlFlags.ConnectionReset);
                tmp.AllowBatch = value.HasFlag(MySqlFlags.ConvertZeroDateTime);
                tmp.ConvertZeroDateTime = value.HasFlag(MySqlFlags.DefaultCommandTimeout);
                tmp.IgnorePrepare = value.HasFlag(MySqlFlags.IgnorePrepare);
                tmp.IntegratedSecurity = value.HasFlag(MySqlFlags.IntegratedSecurity);
                tmp.InteractiveSession = value.HasFlag(MySqlFlags.InteractiveSession);
                tmp.Logging = value.HasFlag(MySqlFlags.Logging);
                tmp.OldGuids = value.HasFlag(MySqlFlags.OldGuids);
                tmp.PersistSecurityInfo = value.HasFlag(MySqlFlags.PersistSecurityInfo);
                tmp.Pooling = value.HasFlag(MySqlFlags.Pooling);
                tmp.Replication = value.HasFlag(MySqlFlags.Replication);
                tmp.RespectBinaryFlags = value.HasFlag(MySqlFlags.RespectBinaryFlags);
                tmp.SqlServerMode = value.HasFlag(MySqlFlags.SqlServerMode);
                tmp.TableCaching = value.HasFlag(MySqlFlags.TableCaching);
                tmp.TreatBlobsAsUTF8 = value.HasFlag(MySqlFlags.TreatBlobsAsUTF8);
                tmp.TreatTinyAsBoolean = value.HasFlag(MySqlFlags.TreatTinyAsBoolean);
                tmp.UseAffectedRows = value.HasFlag(MySqlFlags.UseAffectedRows);
                tmp.UseCompression = value.HasFlag(MySqlFlags.UseCompression);
                tmp.UsePerformanceMonitor = value.HasFlag(MySqlFlags.UsePerformanceMonitor);
                tmp.UseUsageAdvisor = value.HasFlag(MySqlFlags.UseUsageAdvisor);
                this._BooleanFlags = value;
            }
        }
        private MySqlFlags _BooleanFlags;
        /// <summary>
        /// Create new Connection based on user and password authentication
        /// </summary>
        /// <param name="server">Database Instance/Server</param>
        /// <param name="user">User ID</param>
        /// <param name="password"></param>
        public MySqlConnectionInfo(String server, String user, String password)
            : base(Databases.MySql, server, user, password)
        {
        }
        /// <summary>
        /// Create new MySQL ConnectionInfo based on MySqlConnectionStringBuilder.
        /// </summary>
        /// <param name="mcsb">MySqlConnectionStringbuilder</param>
        public MySqlConnectionInfo(MySql.Data.MySqlClient.MySqlConnectionStringBuilder mcsb)
            : base(Databases.MySql, mcsb)
        {
        }
        /// <summary>
        /// Create new Oracle Connection String Builder
        /// </summary>
        /// <returns></returns>
        protected override System.Data.Common.DbConnectionStringBuilder GetConnectionStringbuilder()
        {
            this.ClientFactory = MySql.Data.MySqlClient.MySqlClientFactory.Instance;
            var result = this.ClientFactory.CreateConnectionStringBuilder() as MySql.Data.MySqlClient.MySqlConnectionStringBuilder;
            result.Database = this.Server;
            if (String.IsNullOrEmpty(base.UserName) == false)
                result.UserID = this.UserName;
            if (String.IsNullOrEmpty(base.Password) == false)
                result.Password = this.Password;
            return result;
        }
        /// <summary>
        /// Create new Db Parameter
        /// </summary>
        /// <param name="name">Parameter Name</param>
        /// <param name="value">Parameter Value</param>
        /// <param name="type">Use MySql.Data.MySqlClient.MySqlDbType for inserted parameter</param>
        /// <param name="isNullable">if true, empty object will be converted to DbNull.Value</param>
        /// <param name="Size">Object Size.</param>
        /// <returns>Return new DbParameter</returns>
        public override System.Data.Common.DbParameter CreateParameter(string name, object value, object type, bool isNullable, int Size = 0)
        {
            var param = this.ClientFactory.CreateParameter() as MySql.Data.MySqlClient.MySqlParameter;
            param.ParameterName = name;
            param.Value = (isNullable && value == null) ? DBNull.Value : value;
            param.Size = Size;
            if (type is System.Data.SqlDbType)
                param.MySqlDbType = (MySql.Data.MySqlClient.MySqlDbType)type;
            else if (type is System.Data.DbType)
                param.DbType = (System.Data.DbType)type;
            else
                throw new ArgumentException("Could not recognize Db Type");
            param.IsNullable = isNullable;
            return param;
        }
        /// <summary>
        /// Create new Db Parameter. Autodetect parameter value type
        /// </summary>
        /// <param name="name">Parameter Name</param>
        /// <param name="value">Parameter Value</param>
        /// <param name="isNullable">if true, empty object will be converted to DbNull.Value</param>
        /// <param name="Size">Object Size.</param>
        /// <returns>Return new DbParameter</returns>
        public override System.Data.Common.DbParameter CreateParameter(string name, object value, bool isNullable, int Size = 0)
        {
            return this.CreateParameter(name, value, DbTypeConverter.ToDbType(value), isNullable, Size);
        }
    }
}
